09_Data handling with R

Author

Yeong Chan Lee

Published

April 9, 2023

9-1. R을 활용한 데이터 처리

지금까지 통계 분석법에 대해 배웠다면 지금 9강에서는 데이터 처리를 하기 위한 R 문법을 배우는데 집중하겠습니다. 이때 데이터를 건강보험공단 교육용 표본DB를 활용하도록 하겠습니다. 각 테이블에 대한 설명과 변수 설명은 코딩북을 참고하세요.

library(dplyr)

Attaching package: 'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
library(data.table)

Attaching package: 'data.table'
The following objects are masked from 'package:dplyr':

    between, first, last
bnc <- fread("data/nhis_edu/nsc2_edu_bnc.txt", data.table = FALSE)

bnd <- fread("data/nhis_edu/nsc2_edu_bnd.txt", data.table = FALSE)
bnd$BTH_YYYY <- ifelse(bnd$BTH_YYYY == "1921LE", "1921", bnd$BTH_YYYY)
bnd$BTH_YYYY <- as.numeric(bnd$BTH_YYYY)
set.seed(1234)
bnd$BTH_YYYY <- bnd$BTH_YYYY + sample(0:9, nrow(bnd), replace = TRUE)
bnd <- filter(bnd, BTH_YYYY < 2000)

g1e <- fread("data/nhis_edu/nsc2_edu_g1e.txt", data.table = FALSE)
m20 <- fread("data/nhis_edu/nsc2_edu_m20.txt", data.table = FALSE)

colnames(bnc)
 [1] "STD_YYYY"     "RN_INDI"      "SEX"          "SGG"          "GAIBJA_TYPE" 
 [6] "CTRB_Q10"     "DSB_SVRT_CD"  "DSB_TYPE_CD"  "G1E_OBJ_YN"   "SMPL_TYPE_CD"

9-2. 조건문과 반복문

if 문 - 조건문

조건문이란 주어진 조건에 따라 실행하는 구문이 달라야 할 경우에 사용합니다. 조건에 대해 참 또는 거짓을 판단하고 그에 따라 다른 코드를 실행하게 합니다. 예를 들어, 친구랑 저녁에 무엇을 먹을지 고민하는 상황이라고 합시다. 친구가 동의하면 고기를 먹으려고 합니다.

me <- "오늘 고기 먹을래?"

friends_agree <- FALSE

if(friends_agree){
  me <- "좋아 삼겹살 먹자!"
} else {
  me <- "그럼 뭐 먹을건데 ㅡㅡ"
}
print(me)
[1] "그럼 뭐 먹을건데 ㅡㅡ"

if 다음에 나오는 괄호 안에는 참 또는 거짓으로 평가되는 표현식이어야 합니다. 이를 한줄로 표현하기 위해서 ifelse() 함수를 사용할 수 있습니다.

me <- "오늘 고기 먹을래?"

friends_agree <- FALSE

me <- ifelse(friends_agree, "좋아 삼겹살 먹자!", "그럼 뭐 먹을건데 ㅡㅡ")
print(me)
[1] "그럼 뭐 먹을건데 ㅡㅡ"

조건이 여러 개인 경우 else if를 활용하면 됩니다.

beverages <- c("콜라", "사이다", "쥬스")
my_wish <- beverages[1]

if(my_wish == "콜라"){
  price <- 2500
} else if(my_wish == "사이다"){
  price <- 2300
} else {
  price <- 1900
}


print(paste0(my_wish, "는 ", price, "원입니다."))
[1] "콜라는 2500원입니다."

ifelse() 함수를 활용하려면 다음과 같이 하면 됩니다.

price <- ifelse(my_wish == "콜라", 2500, 
                ifelse(my_wish == "사이다", 2300, 1900))

print(paste0(my_wish, "는 ", price, "원입니다."))
[1] "콜라는 2500원입니다."

이번엔 건보공단 데이터 3000명 자료에서 2006년 기준 나이 50세 미만, 50-70세 미만, 70세 이상 세 그룹으로 나누는 변수를 만들어보겠습니다.

bnd$AGE <- 2006 - bnd$BTH_YYYY
bnd$AGE_GROUP <- ifelse(bnd$AGE < 50, 0, 
                        ifelse((50 <= bnd$AGE) & (bnd$AGE < 70), 1,
                               ifelse(bnd$AGE >= 70, 2, -1)))
table(bnd$AGE_GROUP)

   0    1    2 
1998  590  176 

for 문 - 반복문

프로그래밍을 하는 이유 중 하나는 반복수행을 컴퓨터에게 시키기 위함입니다. R에서 반복문은 주로 for문 씁니다.

for(i in 1:10){ # i가 가질 수 있는 갯수만큼 반복
  print(i)
}
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
[1] 8
[1] 9
[1] 10
my_cumsum <- 0
for(i in 1:10){
  my_cumsum <- my_cumsum + i
}
print(my_cumsum)
[1] 55

다양한 예제로 직접 시도하여 if문과 for문을 익히시길 바랍니다. if문과 for문은 또한 프로그래밍 문법의 기본이니 잘 알아두시면 유용할 것입니다.

9-3. dplyr 라이브러리를 활용한 데이터 처리

지금까지 강의에서 중간중간 dplyr 패키지의 함수들을 다뤘습니다. 이번 기회에 좀 더 자세하게 살펴보겠습니다. dplyr 패키지는 대체로 함수가 직관적으로 만들어져 있어 금방 익힐 수 있고 빠르고 또 다양한 상황의 데이터 처리 함수를 제공합니다. Cheatsheet도 함께 보면서 공부해보세요.

filter

filter함수는 특정 조건에 해당 하는 행(row)을 추출합니다. 그간 예제에서 자주 사용하여 금방 아실 것입니다. 예를 들어, 자격 테이블(bnc)에서 남자들만 추출해봅시다. 첫 번째는 타겟하는 데이터셋, 다음은 조건이 들어가면 됩니다. 조건은 다양하게 입력할 수 있습니다. 이번엔 STD_YYYY가 2006이고 그 중 남자들만 뽑아봅시다.

bnc_man <- filter(bnc, SEX == 1)
bnc_2006_man <- filter(bnc, (STD_YYYY == 2006) & (SEX == 1))

and를 나타내는 &, or를 나타내는 | 또한 잘 알아두세요.

이번엔 STD_YYYY가 2006 또는 2008이고 그중 남자만 뽑는다면 어떻게 해야할까요?

bnc_2006_2008_man <- filter(bnc, ((STD_YYYY == 2006) | STD_YYYY == 2008) & (SEX == 1))

## 또는

bnc_2006_2008_man <- filter(bnc, (STD_YYYY %in% c(2006, 2008)) & (SEX == 1))

or ( | )로 해도 되고 복수개의 동일 여부를 물어보는 %in%(group membership)를 사용해도 됩니다.

이번엔 사망 테이블(bnd)을 활용해서 2006년 기준 age가 50세 이상인 사람들을 뽑아보세요.

select

보통 데이터 처리를 하다보면 본인이 원하는 변수만 추려서 뽑고자 합니다. 그 때 select함수를 쓸 수 있습니다. 자격테이블에서 STD_YYYY가 2006이고 그 때 RN_INDI, SEX, SGG만 뽑아봅시다.

bnc_2006 <- filter(bnc, STD_YYYY == 2006)
bnc_2006 <- select(bnc_2006, RN_INDI, SEX, SGG)

## 또는

bnc_2006 <- filter(bnc, STD_YYYY == 2006) %>% select(RN_INDI, SEX, SGG)

%>% (pipe)를 활용해서 좀 더 간결하고 직관적으로 표현할 수 있습니다.

select함수로 특정 열만 뺄 수도 있습니다. bnc_2006에서 SGG 변수를 빼봅시다.

bnc_2006 <- select(bnc_2006, -SGG)

이번엔 건강검진 테이블(g1e)에서 RN_INDI, G1E_BMI, G1E_BP_SYS, G1E_BP_DIA, G1E_TOT_CHOL, Q_SMK_YN 변수를 뽑겠습니다. 그리고 각 변수에서 missing value가 있는 행은 제거하겠습니다.

cohort <- g1e %>% select(RN_INDI, G1E_BMI, G1E_BP_SYS, G1E_BP_DIA, G1E_TOT_CHOL, Q_SMK_YN) %>% 
  filter(!is.na(G1E_BMI) & !is.na(G1E_BP_SYS) & !is.na(G1E_BP_DIA) & !is.na(G1E_TOT_CHOL) & !is.na(Q_SMK_YN))

group_by

group_by 함수는 말그대로 group 별로 무언가 하고 싶을 때 쓰는 변수 입니다. 예제를 보는 것이 바로 와닿을 것 같습니다. 이번엔 bnc_2006에서 남자, 여자 그룹의 n수를 구해본다고 합시다. 이 때, N수를 구하는 것처럼 요약 정보를 만들고자 할 때는 주로 summarise 함수를 활용합니다.

bnc_2006_n <- bnc_2006 %>% group_by(SEX) %>% summarise(N = n())

이번엔 cohort에서 Q_SMK_YN 값에 따라서 BMI의 평균과 표준편차를 구해보겠습니다.

cohort_smk_bmi_summary <- cohort %>% group_by(Q_SMK_YN) %>% summarise(BMI_MEAN = mean(G1E_BMI), BMI_SD = sd(G1E_BMI))

교육용 표본DB의 3000명에 대해서 검진 테이블에는 2006, 2008, 2010, 2012년 사이에 건강검진을 받은 경우 기록이 되어 있기 때문에 한 사람이 여러번 진단을 받았을 수도 있습니다. 3000명 중에서 건강검진을 받았는 사람들이 몇 명이고, 또 여러 번 받은 사람들이 몇 명인지 알아보려면 어떻게 해야 할까요? 관심 변수의 missing value를 제거한 cohort데이터로 살펴보겠습니다.

cohort_n_summary <- cohort %>% group_by(RN_INDI) %>% summarise(N = n())
nrow(cohort_n_summary)
[1] 1162
nrow(filter(cohort_n_summary, N > 1))
[1] 666
summary(cohort_n_summary$N)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.000   1.000   2.000   2.096   3.000   4.000 

cohort에 포함된 사람들의 BMI, SBP, DBP, total chol., smoking 변수의 대푯값을 구하겠습니다. 특히 여러 번 건강검진을 받은 사람들의 BMI, SBP, DBP, total chol.은 평균, smoking 변수는 max 값으로 구하기로 정의합시다.

cohort <- cohort %>% group_by(RN_INDI) %>% summarise(BMI = mean(G1E_BMI), 
                                  BP_SYS = mean(G1E_BP_SYS), 
                                  BP_DIA = mean(G1E_BP_DIA),
                                  TOT_CHOL = mean(G1E_TOT_CHOL),
                                  SMK = max(Q_SMK_YN))

즉, group_by함수를 활용해 자신이 원하는 그룹의 요약통계량이나 대푯값을 어렵지 않게 코드 한 줄로 구할 수 있습니다.

arrange

arrange는 말그대로 배치하는 것인데 특정 열을 기준으로 테이블을 sorting을 할 때 씁니다. 예를 들어 bnd에서 BTH_YYYY를 기준으로 오름차순 정렬해봅시다.

tmp_bnd <- bnd %>% arrange(BTH_YYYY)

빠른 생년 기준으로 정렬된 것이 보이나요? 만약에 내림차순으로 정렬한다면 어떻게 해야할까요? desc()함수를 함께 써줍니다.

tmp_bnd <- bnd %>% arrange(desc(BTH_YYYY))

distinct

벡터에서 값들을 unique하게 보고 싶다면 unique 함수를 쓰면 됩니다. 마찬가지로 데이터프레임에서 특정 열을 기준으로 unique하게 뽑고 싶다면 distinct함수를 사용합니다. 예를 들어, g1e 테이블에는 한 사람이 건강검진을 여러 번을 받았다는 것이 기록 되어 있습니다. 만약에 g1e에서 사람들을 unique하게 뽑고 싶다면 어떻게 해야할까요?

unique(cohort$Q_SMK_YN)
Warning: Unknown or uninitialised column: `Q_SMK_YN`.
NULL
tmp_g1e <- g1e %>% distinct(RN_INDI)

tmp_g1e를 보시면 RN_INDI말고 모든 변수가 사라졌습니다. 만약 나머지 변수들도 함께 뽑고 싶다면 .keep_all=True 옵션을 줍니다. 이 때, 한 사람이 여러 번 건강검진을 받았다면 g1e 테이블에서 가장 첫번째 row만 가져오게 됩니다.

tmp_g1e <- g1e %>% distinct(RN_INDI, .keep_all = TRUE)

mutate

mutate는 새로운 열을 만들 때 쓰이는 함수입니다. $ 로 만들어서 할 수도 있지만 pipe를 함께 쓸 땐 mutate로 열을 만드는 것이 코드를 더 간결하게 할 것입니다. bnd에서 2006년 기준 나이 변수를 mutate 함수를 활용해 만들어 봅시다.

bnd$AGE <- 2006 - bnd$BTH_YYYY

## 또는

bnd <- bnd %>% mutate(AGE = 2006 - BTH_YYYY)

여러 개의 열을 한꺼번에 만들 수도 있습니다.

bnd <- bnd %>% mutate(AGE = 2006 - BTH_YYYY, 
                      AGE_GROUP = ifelse(AGE < 50, 1,
                                         ifelse((50 <= AGE) & (AGE < 70), 2,
                                                ifelse(AGE >= 70, 3, -1))))

rename

rename은 열의 이름을 바꾸고자 할 때 유용하게 쓸 수 있는 함수입니다. 예제를 보시면 금방 이해할 수 있습니다. AGE 변수를 age로 바꿔보겠습니다.

bnd <- bnd %>% rename(age = AGE)

저는 보통 열의 이름을 모두 대문자로 하기 때문에 다시 AGE로 바꿀게요.

bnd <- bnd %>% rename(AGE = age)

9-4. 테이블의 결합 (Join)

데이터의 변수가 많아질수록 한 테이블에 담기가 어려워집니다. 보기도 힘들어집니다. 그래서 공통된 특성끼리 묶어 여러 개의 테이블을 만듭니다. 자격, 사망, 명세서 등 테이블이 여러 개가 있는 건보공단 데이터도 그렇습니다. 그럼 테이블을 결합할 땐 어떤 방식으로 할까요? 이 때 알아야 할 개념이 key입니다. 두 테이블을 연결해줄 공통적인 열을 의미합니다.

현재 AGE변수는 bnd에 있고 BMI 변수는 cohort에 있습니다. 이를 하나의 테이블에서 보려면 어떻게 해야 할까요? 사람별로 AGE, BMI 변수를 찾아 합쳐줘야 할텐데 개인식별아이디 RN_INDI를 사용할 수 있을 것입니다. 여기서 RN_INDI가 key가 됩니다.

한 가지 더 알아야 하는 것은 어느 테이블을 기준으로 합칠 것인지 또는 합집합, 교집합으로 합칠 것인지 따져야 합니다. 아래 cheatsheet의 예제를 보면서 비교해보세요.

목적에 따라 left_join을 할지, inner_join을 할지, full_join을 할지 그때 그때 다르기 때문에 잘 이해했다가 적용해야합니다. cohort 데이터에 건강검진 변수가 있는데 여기에 AGE 변수를 합치도록 하겠습니다. 그러면 cohort 데이터를 기준으로 합치는 것이니 left_join이 적절할 것입니다.

cohort2 <- left_join(cohort, select(bnd, RN_INDI, AGE), by = "RN_INDI")
nrow(cohort2)
[1] 1162

이번엔 bnc테이블의 SEX 변수도 함께 합치겠습니다.

cohort3 <- left_join(cohort2, select(bnc, RN_INDI, SEX), by = "RN_INDI")
Warning in left_join(cohort2, select(bnc, RN_INDI, SEX), by = "RN_INDI"): Each row in `x` is expected to match at most 1 row in `y`.
ℹ Row 1 of `x` matches multiple rows.
ℹ If multiple matches are expected, set `multiple = "all"` to silence this
  warning.
nrow(cohort3)
[1] 4624

경고와 함께 cohort3의 행의 수가 더 많아졌습니다. 왜 그런 것인가요? bnc테이블에 환자가 중복되어 있기 때문에 합쳤을 때 수가 늘어난 것입니다. 현재는 cohort 데이터에 환자가 중복되어 있지 않게끔 구성하고 싶기 때문에 원하는 바대로 합쳐지지 않았습니다. 그렇기 때문에 다음과 같이 해야 합니다.

cohort3 <- left_join(cohort2, 
                     select(bnc, RN_INDI, SEX) %>% distinct(RN_INDI, .keep_all = TRUE), 
                     by = "RN_INDI")
nrow(cohort3)
[1] 1162

방금 예시를 통해 보았듯 데이터를 조인하게 될 경우가 빈번하게 생길텐데 그럴 때 본인이 갖고 있는 테이블들의 키가 중복되어 있는지 unique하게 하나씩만 있는지 잘 파악하면서 데이터처리를 해야 합니다.

9-5. 건보공단 데이터에 적용하기

데이터 처리를 할 때 잘 쓰는 dplyr 패키지의 함수를 배웠습니다. 이외에 또 다양한 상황에 맞는 함수가 존재합니다. 그러니 만들고자 하는 데이터의 형태가 어떻게 되어야 할지 생각해서 그에 맞는 함수를 찾으면 됩니다.

이제는 지금까지 배운 함수를 토대로 중간 시험에서 사용했던 cohort를 만들어보려고 합니다. 잘 해석해보도록 합시다.

library(dplyr)
library(data.table)
library(moonBook)


bnc <- fread("data/nhis_edu/nsc2_edu_bnc.txt", data.table = FALSE)
bnc_2006 <- filter(bnc, STD_YYYY == 2006)
bnd <- fread("data/nhis_edu/nsc2_edu_bnd.txt", data.table = FALSE)
bnd$BTH_YYYY <- ifelse(bnd$BTH_YYYY == "1921LE", "1921", bnd$BTH_YYYY)
bnd$BTH_YYYY <- as.numeric(bnd$BTH_YYYY)
set.seed(1234)
bnd$BTH_YYYY <- bnd$BTH_YYYY + sample(0:9, nrow(bnd), replace = TRUE)
g1e <- fread("data/nhis_edu/nsc2_edu_g1e.txt", data.table = FALSE)
g1e_2006 <- filter(g1e, EXMD_BZ_YYYY == 2006)
m20 <- fread("data/nhis_edu/nsc2_edu_m20.txt", data.table = FALSE)



coh_people <- g1e %>% select(RN_INDI, G1E_BMI, G1E_BP_SYS, G1E_BP_DIA, G1E_TOT_CHOL, Q_SMK_YN) %>% 
  filter(!is.na(G1E_BMI) & !is.na(G1E_BP_SYS) & !is.na(G1E_BP_DIA) & !is.na(G1E_TOT_CHOL) & !is.na(Q_SMK_YN)) %>%
  group_by(RN_INDI) %>% summarise(BMI = mean(G1E_BMI), 
                                  BP_SYS = mean(G1E_BP_SYS), 
                                  BP_DIA = mean(G1E_BP_DIA),
                                  TOT_CHOL = mean(G1E_TOT_CHOL),
                                  SMK = max(Q_SMK_YN))
  
coh_people <- left_join(coh_people, select(bnc_2006, RN_INDI, SEX), by = "RN_INDI")
coh_people <- left_join(coh_people, select(bnd, RN_INDI, BTH_YYYY), by = "RN_INDI")
coh_people$AGE <- 2006 - coh_people$BTH_YYYY


event_code <- c("I10")
m20_2 <- filter(m20, RN_INDI %in% coh_people$RN_INDI)
m20_event <- filter(m20_2, grepl(paste0(event_code, collapse = "|"), SICK_SYM1) | grepl(paste0(event_code, collapse = "|"), SICK_SYM2))
m20_event_2 <- m20_event %>% group_by(RN_INDI) %>% filter(MDCARE_STRT_DT == min(MDCARE_STRT_DT)) %>% select(RN_INDI, MDCARE_STRT_DT) %>% distinct(RN_INDI, .keep_all = TRUE)
m20_event_2$YEAR <- as.numeric(substr(m20_event_2$MDCARE_STRT_DT, 1, 4))
m20_event_2$HYP <- 1


event2_code <- c(paste0("I", 20:25))
m20_2 <- filter(m20, RN_INDI %in% coh_people$RN_INDI)
m20_event2 <- filter(m20_2, grepl(paste0(event2_code, collapse = "|"), SICK_SYM1) | grepl(paste0(event2_code, collapse = "|"), SICK_SYM2))
m20_event2_2 <- m20_event2 %>% group_by(RN_INDI) %>% filter(MDCARE_STRT_DT == min(MDCARE_STRT_DT)) %>% select(RN_INDI, MDCARE_STRT_DT) %>% distinct(RN_INDI, .keep_all = TRUE)
m20_event2_2$YEAR <- as.numeric(substr(m20_event2_2$MDCARE_STRT_DT, 1, 4))
m20_event2_2$IHD <- 1


coh_people2 <- left_join(coh_people, select(m20_event_2, RN_INDI, HYP, MDCARE_STRT_DT) %>% rename(HYP_DATE = MDCARE_STRT_DT), by = "RN_INDI")
coh_people2$HYP <- ifelse(is.na(coh_people2$HYP), 0, coh_people2$HYP)

coh_people2 <- left_join(coh_people2, select(m20_event2_2, RN_INDI, IHD, MDCARE_STRT_DT) %>% rename(IHD_DATE = MDCARE_STRT_DT), by = "RN_INDI")
coh_people2$IHD <- ifelse(is.na(coh_people2$IHD), 0, coh_people2$IHD)

coh_people2 <- as.data.frame(coh_people2)


set.seed(1234)
coh_people2$RN_INDI <- coh_people2$RN_INDI + sample(1:100, nrow(coh_people2), replace = TRUE)
coh_people2 <- select(coh_people2, RN_INDI, SEX, BTH_YYYY, AGE, BMI, BP_SYS, BP_DIA, TOT_CHOL, SMK, HYP, HYP_DATE, IHD, IHD_DATE)

fwrite(coh_people2, "data/hyp_ihd_cohort.csv")

문제풀이를 하겠습니다.

library(dplyr)
library(data.table)
library(moonBook)

# 1.
data <- fread("data/hyp_ihd_cohort.csv", data.table = FALSE)

# 3.
length(which(is.na(data$RN_INDI)))
[1] 0
length(which(is.na(data$SEX)))
[1] 0
length(which(is.na(data$AGE)))
[1] 0
length(which(is.na(data$BMI)))
[1] 0
length(which(is.na(data$BP_SYS)))
[1] 0
length(which(is.na(data$BP_DIA)))
[1] 0
length(which(is.na(data$TOT_CHOL)))
[1] 0
length(which(is.na(data$SMK)))
[1] 0
length(which(is.na(data$HYP)))
[1] 0
length(which(is.na(data$IHD)))
[1] 0
# 4.
mytable(HYP~SEX+AGE+BMI+BP_SYS+BP_DIA+TOT_CHOL+SMK+IHD, data=data)

     Descriptive Statistics by 'HYP'    
————————————————————————————————————————— 
               0            1         p  
            (N=871)      (N=291)   
————————————————————————————————————————— 
 SEX                                0.002
   - 1    453 (52.0%)  120 (41.2%)       
   - 2    418 (48.0%)  171 (58.8%)       
 AGE      38.6 ± 14.0  55.5 ± 12.7  0.000
 BMI      23.3 ±  3.3  24.8 ±  2.9  0.000
 BP_SYS   119.0 ± 12.1 132.2 ± 14.5 0.000
 BP_DIA   74.7 ±  8.4  81.1 ±  9.4  0.000
 TOT_CHOL 192.9 ± 33.5 201.5 ± 33.7 0.000
 SMK                                0.002
   - 1    509 (58.4%)  201 (69.1%)       
   - 2     93 (10.7%)   30 (10.3%)       
   - 3    269 (30.9%)   60 (20.6%)       
 IHD                                0.000
   - 0    846 (97.1%)  230 (79.0%)       
   - 1     25 ( 2.9%)   61 (21.0%)       
————————————————————————————————————————— 
# 5.
data2 <- filter(data, AGE < 40)
data2$HYP_SYS <- ifelse(data2$BP_SYS >= 140, 1, 0)

table(data2$HYP_SYS)

  0   1 
484  19 
round(table(data2$HYP_SYS)/nrow(data2), 3)

    0     1 
0.962 0.038 
# 6.
data3 <- filter(data, AGE >= 40)
data3$HYP_SYS <- ifelse(data3$BP_SYS >= 140, 1, 0)

table(data3$HYP_SYS)

  0   1 
559 100 
round(table(data3$HYP_SYS)/nrow(data3), 3)

    0     1 
0.848 0.152 
# 7-8.
t.test(filter(data, HYP == 1)$TOT_CHOL, filter(data, HYP == 0)$TOT_CHOL)

    Welch Two Sample t-test

data:  filter(data, HYP == 1)$TOT_CHOL and filter(data, HYP == 0)$TOT_CHOL
t = 3.7837, df = 495.11, p-value = 0.0001735
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
  4.138246 13.078552
sample estimates:
mean of x mean of y 
 201.5006  192.8922 
wilcox.test(filter(data, HYP == 1)$TOT_CHOL, filter(data, HYP == 0)$TOT_CHOL)

    Wilcoxon rank sum test with continuity correction

data:  filter(data, HYP == 1)$TOT_CHOL and filter(data, HYP == 0)$TOT_CHOL
W = 145712, p-value = 0.0001283
alternative hypothesis: true location shift is not equal to 0
# 9.
table(data$HYP, data$IHD)
   
      0   1
  0 846  25
  1 230  61
chisq.test(data$HYP, data$IHD)

    Pearson's Chi-squared test with Yates' continuity correction

data:  data$HYP and data$IHD
X-squared = 101.55, df = 1, p-value < 2.2e-16